package com.matthicks.macrobot.pdfocr;

import java.awt.Point;
import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;

import com.matthicks.macrobot.Key;
import com.matthicks.macrobot.RemoteController;

public class PDFOCR {
	public static final float time = 1.0f;
	
	private RemoteController rc;
	
	public PDFOCR() throws UnknownHostException, IOException {
		rc = new RemoteController("192.168.42.128", 2600);
	}
	
	boolean created = false;

	public void processDirectory(File directory) throws IOException {
		File[] files = directory.listFiles();
		for (int i = 0; i < files.length; i++) {
			//progressset(Math.round(((float)(i + 1) / (float)files.length) * 100.0f), "Extracting Text: " + files[i]);
			if (files[i].isDirectory()) {
				processDirectory(files[i]);
			} else if (!files[i].getName().startsWith(".")) {
				if (!files[i].isHidden()) {
					File f = files[i];
					if (f.getName().toLowerCase().endsWith(".txt")) {
						continue;
					}
					System.out.println("Processing(" + i + "): " + f.getAbsolutePath());
					
					if (!f.getName().toLowerCase().endsWith(".pdf")) {
						System.out.println("\tNo .pdf extension, renaming...");
						File fn = new File(directory, f.getName() + ".pdf");
						f.renameTo(fn);
						f = fn;
					}
					if ((f.getName().indexOf('#') != -1) || (f.getName().indexOf(' ') != -1) || (f.getName().indexOf('_') != -1) || (f.getName().indexOf('?') != -1) || (f.getName().indexOf(',') != -1)) {
						String name = f.getName();
						name = name.substring(0, name.length() - 4);
						name = name.replaceAll("#", "");
						name = name.replaceAll(" ", "");
						name = name.replaceAll("_", "");
						name = name.replaceAll("[?]", "");
						name = name.replaceAll("[,]", "");
						File fn = new File(directory, name + ".pdf");
						int increment = 0;
						while (fn.exists()) {
							increment++;
							fn = new File(directory, name + increment + ".pdf");
						}
						f.renameTo(fn);
						f = fn;
					}
					File txt = new File(directory, f.getName().substring(0, f.getName().length() - 4) + ".txt");
					if (!txt.exists()) {
						if (openPDF(f, time)) {
							convertPDF(time);
							if (!closeNotepad(time)) {
								rc.mouseMove(300, 300, time);
								rc.delay(5);
								convertPDF(time);
								if (!closeNotepad(time)) {
									System.err.println("\tFailed to close notepad");
								} else {
									System.out.println("\tSuccessfully converted after second attempt");
								}
							}
						} else {
							txt.createNewFile();
						}
					} else {
						System.out.println("\tSkipping: already created Text file");
					}
				}
			}
		}
	}

	public void killPDFTransformer() {
		rc.killProcess("Transformer.exe");
	}

	public void launchPDFTransformer() {
		if (!rc.isProcessRunning("Transformer.exe")) {
			rc.keyPress(Key.CONTROL);
			rc.keyPress(Key.ALT);
			rc.keyType(Key.p);
			rc.keyRelease(Key.ALT);
			rc.keyRelease(Key.CONTROL);
		}
	}

	public boolean openPDF(File file, float time) {
		String pdfName = file.getAbsolutePath();
		
		closeWarnings(time);

		pdfName = pdfName.replaceAll("/", "\\\\");

		Point p = rc.screenContains(0, 0, "abbyy_open_pdf.png", 5.0f, 5);
		if (p == null) {
			throw new RuntimeException("Unable to find Open PDF button");
		}
		rc.mouseMove(p.x, p.y, time);
		rc.mouseClick();
		if (rc.screenContains(0, 0, "abbyy_output_dialog.png", 5.0f, 5) == null) {
			rc.mouseMove(p.x, p.y, time);
			rc.mouseClick();
			if (rc.screenContains(0, 0, "abbyy_output_dialog.png", 5.0f, 15) == null) {
				throw new RuntimeException("Unable to find open dialog");
			}
		}
		rc.stringType(pdfName);
		rc.keyType(Key.ENTER);
		rc.delay(5);
		if (rc.screenContains(0, 0, "abbyy_pdf_opened.png", 5.0f, 12) == null) {
			if (noWarnings(time)) {
				System.err.println("PDF did not open successfully");
				return false;
			} else {
				return false;
			}
		}
		return true;
	}

	public boolean noWarnings(float time) {
		// Check for error dialog
			if (rc.screenContains(0, 0, "abbyy_fatal_error.png", 0.0f, 1) != null) {
				System.err.println("\tError during open of PDF");
				Point p = rc.screenContains(0, 0, "abbyy_close_warning.png", 0.0f, 1);
				rc.mouseMove(p.x, p.y, time);
				rc.mouseClick();
				return false;
			} else if (rc.screenContains(0, 0, "abbyy_output_dialog.png", 5.0f, 2) != null) {
				System.err.println("\tFilename not accepted in open-dialog.");
				return false;
			}
		return true;
	}

	public void convertPDF(float time) {
		Point p = rc.screenContains(0, 0, "abbyy_convert_pdf.png", 5.0f, 12);
		while (p == null) {
			rc.delay(5);
			p = rc.screenContains(0, 0, "abbyy_convert_pdf.png", 0.0f, 1);
		}
		if (p == null) {
			throw new RuntimeException("Unable to find Convert PDF button");
		}
		rc.mouseMove(p.x, p.y, time);
		rc.mouseClick();
	}

	public boolean closeNotepad(float time) {
		while (true) {
			if (rc.screenContains(0, 0, "abbyy_notepad.png", 5.0f, 3) == null) {
				if (rc.screenContains(0, 0, "abbyy_converting.png", 0.0f, 1) != null) {
					continue;
				} else if (rc.screenContains(0, 0, "abbyy_notepad.png", 0.0f, 1) != null) {
					break;
				} else {
					System.err.println("Unable to find Notepad in order to close");
					return false;
				}
			} else {
				break;
			}
		}
		rc.keyPress(Key.ALT);
		rc.keyType(Key.F4);
		rc.keyRelease(Key.ALT);

		// Check for warning dialog
		rc.delay(2);
		closeWarnings(time);

		created = true;

		return true;
	}

	public void closeWarnings(float time) {
		if (rc.screenContains(0, 0, "abbyy_warning.png", 0.0f, 1) != null) {
			System.err.println("\tWarning during conversion");
			Point p = rc.screenContains(0, 0, "abbyy_close_warning.png", 0.0f, 1);
			rc.mouseMove(p.x, p.y, time);
			rc.mouseClick();
		} else if (rc.screenContains(0, 0, "abbyy_fatal_error.png", 0.0f, 1) != null) {
			System.err.println("\tError during conversion");
			Point p = rc.screenContains(0, 0, "abbyy_close_warning.png", 0.0f, 1);
			rc.mouseMove(p.x, p.y, time);
			rc.mouseClick();
		} else if (rc.screenContains(0, 0, "abbyy_not_found.png", 0.0f, 1) != null) {
			System.err.println("\tFile not found");
			rc.keyType(Key.ENTER);
			rc.delay(2);
			rc.keyType(Key.ESCAPE);
		}
	}

	public void processUntilComplete(File directory, float time) {
		do {
			System.out.println("Launching PDFTransformer");
			launchPDFTransformer();
			try {
				created = false;
				processDirectory(directory);
				break;
			} catch(Throwable t) {
				t.printStackTrace();
			}
			killPDFTransformer();
		} while(created);
	}

	public void disconnect() throws IOException {
		rc.disconnect();
	}
	
	public static void main(String[] args) throws Exception {
		PDFOCR ocr = new PDFOCR();
		try {
			System.out.println("Looking to see if Transformer.exe is running");
			if (ocr.rc.isProcessRunning("Transformer.exe")) {
				System.out.println("Killing Transformer.exe...");
				ocr.killPDFTransformer();
				System.out.println("Killed Transformer.exe, waiting 5 seconds before proceeding");
				ocr.rc.delay(5);
			}
		
			ocr.processUntilComplete(new File("//bluemeanie.imirus.local/ftp/ocrproboat/464"), time);
		} finally {
			ocr.disconnect();
		}
	}
}
